import robot.errors
import robot.parsing.model
from rsa.util.common_utilities import merge

def open_resource(directory, file):
    """ 
    Open a robot resource located in the specified directory
    @return: a robot resource object
    """
    path = merge(directory, file)
    try:
        # TestData is a factory that can read both 
        # robot test files and robot test directories.
        return robot.parsing.model.ResourceFile(source=path)
    except robot.errors.DataError, e:
        print "error opening '%s':" % path, e
        
def open_file(directory, file):
    """ 
    Open a file located in specified directory, 
    @return: a file object.
    """
    path = merge(directory, file)
    try:
        return open(path, 'r')
    except Exception, e:
        print "error opening '%s':" % path, e

def find_suite(parent, suite_name):
    """ 
    Find and return a given suite/test on a suite structure
    @return: a robot test suite 
    """        
    if(parent.name == suite_name):
        return parent
    if(len(parent.testcase_table.tests) == 0):
        for child in parent.children:
            suite = find_suite(child, suite_name)
            if(suite != None):
                return suite
    else:
        for test in parent.testcase_table:
            if(test.name == suite_name):
                return test
    return None

def imported_resources(node, symbols, imports):
    """
    Fills the argument imports with all the resources accessible of a given node
    """
    if(node):
        methods = dir(node)
        if(methods.count("imports") == 0): 
            imported_resources(node.parent, symbols, imports)
        else:
            imported = symbols.get_resources(get_full_name(node))
            if(imported != None):
                imports.extend(imported)
            imported_resources(node.parent, symbols, imports)

def root_suite(suite):
    """
    Returns the root suite of a leaf suite
    @return: the root suite
    """    
    if(suite.parent == None):
        return suite
    else:
        return root_suite(suite.parent)
    
def get_full_name(node):
    """
    Returns the complete name of a node. This name is a concatenation of all the names in the 
    tree structure from the node to the root.
    @return: the node's full name 
    """
    if(node.parent != None):
        if(isinstance(node, robot.parsing.model.TestCaseTable) or 
           isinstance(node, robot.parsing.model.KeywordTable)):
            return get_full_name(node.parent)
        return get_full_name(node.parent) + "." + node.name
    else:
        return node.name

def find_keyword(name, suite):
    """
    Finds a keyword in a suite structure
    @return: a robot keyword 
    """
    # find it locally
    for keyword in suite.keywords:
        if(keyword.name == name):
            return keyword
    # TODO find it in references
    # find it on parent
    if(suite.parent != None):
        return find_keyword(name, suite.parent)
    else:
        return None
    
def to_robot_var(str):
    """
    Returns a robot variable representation of a given string
    @return: a robot variable 
    """
    index1 = str.find("=")
    index2 = str.find(":")
    if(index1 != -1):
        str = str[:index1]
    if(index2 != -1):
        str = str[:index2]
    str = str.replace("\"", "").replace(" ", "").replace("\t", "")
    #return "${" + str + "}"
    return str
